package com.eco.fishway.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eco.common.response.BaseResponse;
import com.eco.common.response.ResultTool;
import com.eco.db.dto.FishStatisticsDTO;
import com.eco.db.dto.RecordDto;
import com.eco.db.dto.TimeRangeDTO;
import com.eco.db.entity.Record;
import com.eco.db.mapper.RecordMapper;
import com.eco.db.vo.FishPassVO;
import com.eco.db.vo.SummaryStatisticsVO;
import com.eco.fishway.service.MinioService;
import com.eco.fishway.service.RecordService;
import com.eco.fishway.service.VideoFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author xulinyu
 * @since 2024-07-18
 */
@Api(tags = "碾盘山特供红外查询接口")
@RestController
@RequestMapping("/ir")
@Slf4j
public class RecordController {

    @Value("${infrared.cache-duration:}")
    private Integer cacheDuration;

    @Value("${infrared.time-range:}")
    private String timeRange;

    @Value("${minio.bucket-name:}")
    private String bucketName;

    private final MinioService minioService;

    private final RedisTemplate redisTemplate;

    private final RecordMapper recordMapper;

    private final RecordService recordService;

    private final VideoFileService videoFileService;

    public RecordController(RedisTemplate redisTemplate, RecordMapper recordMapper, RecordService recordService, MinioService minioService, VideoFileService videoFileService) {
        this.redisTemplate = redisTemplate;
        this.recordMapper = recordMapper;
        this.recordService = recordService;
        this.minioService = minioService;
        this.videoFileService = videoFileService;
    }

    @ApiOperation("鱼种统计")
    @GetMapping("/videoAnalysisFishResult/categoryStatistics")
    public BaseResponse<Object> categoryStatistics() {
        Object res = redisTemplate.opsForValue().get("categoryStatistics");
        if (ObjectUtil.isEmpty(res)) {
            TimeRangeDTO timeRangeDTO = getTimeRange(timeRange);
            res = recordMapper.categoryStatistics(timeRangeDTO);
            redisTemplate.opsForValue().set("categoryStatistics", res, cacheDuration, TimeUnit.MINUTES);
        }
        return ResultTool.success(res);
    }


    @ApiOperation("数量统计")
    @PostMapping("/videoAnalysisFishResult/numberStatistics")
    public BaseResponse<Object> numberStatistics(@RequestBody FishStatisticsDTO fishStatisticsDTO) {
        String redisKey = "ns_" + fishStatisticsDTO.toString();
        Object res = redisTemplate.opsForValue().get(redisKey);
        if (ObjectUtil.isEmpty(res)) {
            res = recordService.numberStatistics(fishStatisticsDTO);
            redisTemplate.opsForValue().set(redisKey, res, cacheDuration, TimeUnit.MINUTES);
        }
        return ResultTool.success(res);
    }


    @ApiOperation("汇总统计")
    @GetMapping("/videoAnalysisFishResult/summaryStatistics")
    public BaseResponse<Object> summaryStatistics() {
        Object res = redisTemplate.opsForValue().get("summaryStatistics");
        if (ObjectUtil.isEmpty(res)) {
            List<SummaryStatisticsVO> list = recordMapper.summaryStatistics();
            res = list.stream().collect(Collectors.groupingBy(SummaryStatisticsVO::getType));
            redisTemplate.opsForValue().set("summaryStatistics", res, cacheDuration, TimeUnit.MINUTES);
        }
        return ResultTool.success(res);
    }


    @ApiOperation("过鱼统计")
    @GetMapping("/stationInfo/passStatistics")
    public BaseResponse<Object> passStatistics() {
        Object res = redisTemplate.opsForValue().get("passStatistics");
        if (ObjectUtil.isEmpty(res)) {
            List<FishPassVO> list = recordMapper.passStatistics();
            Map<String, FishPassVO> resMap = new HashMap<>();
            resMap.put("history", list.get(0));
            resMap.put("today", list.get(1));
            res = resMap;
            redisTemplate.opsForValue().set("passStatistics", res, cacheDuration, TimeUnit.MINUTES);
        }
        return ResultTool.success(res);
    }

    @ApiOperation("过鱼趋势统计")
    @GetMapping("/stationInfo/passTrendStatistics")
    public BaseResponse<Object> passTrendStatistics(@Validated @RequestParam(name = "beginDate") String beginDate, @Validated @RequestParam(name = "endDate") String endDate) {
        String redisKey = "pts_" + beginDate + "_" + endDate;
        Object res = redisTemplate.opsForValue().get(redisKey);
        if (ObjectUtil.isEmpty(res)) {
            res = recordMapper.passTrendStatistics(beginDate, endDate);
            redisTemplate.opsForValue().set(redisKey, res, cacheDuration, TimeUnit.MINUTES);
        }
        return ResultTool.success(res);
    }


    @ApiOperation("过鱼大小统计")
    @GetMapping("/stationInfo/passSizeStatistics")
    public BaseResponse<Object> passSizeStatistics(@Validated @RequestParam(name = "beginDate") String beginDate,
                                                   @Validated @RequestParam(name = "endDate") String endDate,
                                                   @RequestParam(name = "fishCategoryName", required = false) String fishCategoryName) {
        String redisKey = "pss_" + beginDate + "_" + endDate + "_" + fishCategoryName;
        Object res = redisTemplate.opsForValue().get(redisKey);
        if (ObjectUtil.isEmpty(res)) {
            res = recordMapper.passSizeStatistics(beginDate, endDate, fishCategoryName);
            redisTemplate.opsForValue().set(redisKey, res, cacheDuration, TimeUnit.MINUTES);
        }
        return ResultTool.success(res);
    }


    private static TimeRangeDTO getTimeRange(String timeRange) {
        TimeRangeDTO timeRangeDTO = new TimeRangeDTO();
        timeRange = StringUtils.isEmpty(timeRange) ? "week" : timeRange;
        String today = DateUtil.now();
        switch (timeRange) {
            case "day":
                timeRangeDTO.setBeginDate(DateUtil.beginOfDay(new Date()).toString());
                timeRangeDTO.setEndDate(today);
                break;
            case "week":
                timeRangeDTO.setBeginDate(DateUtil.offsetDay(new Date(), -7).toString());
                timeRangeDTO.setEndDate(today);
                break;
            case "month":
                timeRangeDTO.setBeginDate(DateUtil.offsetDay(new Date(), -30).toString());
                timeRangeDTO.setEndDate(today);
                break;
            case "year":
                timeRangeDTO.setBeginDate(DateUtil.beginOfYear(new Date()).toString());
                timeRangeDTO.setEndDate(today);
                break;
            default:
                break;
        }
        log.info(timeRange + " : " + timeRangeDTO.getBeginDate());
        log.info(timeRange + " : " + timeRangeDTO.getEndDate());
        return timeRangeDTO;
    }


    @ApiOperation("查询分页")
    @PostMapping("page")
    public BaseResponse<IPage<Record>> page(@RequestBody RecordDto dto) {
        return ResultTool.success(recordMapper.page(new Page<>(dto.getPageNo(), dto.getPageSize()), dto));
    }

    @ApiOperation("编辑")
    @PostMapping("update")
    public BaseResponse<Object> update(@RequestBody Record record) {
        record.setKinds(record.getCategory());
        recordService.updateById(record);
        return ResultTool.success("更新成功");
    }

    @ApiOperation("删除")
    @PostMapping("delete")
    public BaseResponse<Object> delete(@RequestBody List<Integer> ids) {
        List<String> videoPathList = recordMapper.selectBatchIds(ids).stream().map(x->videoFileService.convertUrlToFilePath(x.getVideoUrl())).collect(Collectors.toList());
        recordMapper.deleteBatchIds(ids);
        //删除记录的时候删除视频
        videoFileService.deleteBatchFiles(videoPathList);
        return ResultTool.success("删除成功");
    }

    @ApiOperation("根据id查询详情")
    @GetMapping("detail")
    public BaseResponse<Record> detail(String recordId) {
        return ResultTool.success(recordMapper.selectById(recordId));
    }


    @ApiOperation("获取精选视频地址")
    @GetMapping("getFavouriteVideoUrlList")
    public BaseResponse<List<String>> getFavouriteVideoUrlList() {
        return ResultTool.success(videoFileService.findAllVideos());
    }
}
